﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SecTool.Core;
using SecTool.Core.Crypto;
using SecTool.WinUI.Properties;

namespace SecTool.WinUI
{
    public partial class SecTool : Form
    {
        private string username;

        private Document document;

        public SecTool(string username)
        {
            InitializeComponent();
            this.username = username;
            toolStripStatusLabel1.Text = String.Format(Resources.StatusUserLabel, username);
            cbEncAlgorithm.DataSource = System.Enum.GetValues(typeof(Core.Crypto.SymmetricAlgorithm));
            cbHashAlgorithm.DataSource = System.Enum.GetValues(typeof(Core.Crypto.HashAlgorithm));
            cbRecipient.DataSource = Core.Crypto.KeyProvider.GetRecipients();
        }

        private void BindDocumentInfo()
        {
            if (document == null) return;
            tbAuthor.DataBindings.Clear();
            tbAuthor.DataBindings.Add("Text", document, "Author");
            tbRecipient.DataBindings.Clear();
            tbRecipient.DataBindings.Add("Text", document, "Recipient");
            tbFileName.DataBindings.Clear();
            tbFileName.DataBindings.Add("Text", document, "Filename");
            cbEncrypted.DataBindings.Clear();
            cbEncrypted.DataBindings.Add("Checked", document, "Encrypted");
            cbSigned.DataBindings.Clear();
            cbSigned.DataBindings.Add("Checked", document, "Signed");
            cbEncAlgorithm.DataBindings.Clear();
            cbEncAlgorithm.DataBindings.Add("SelectedItem", document, "Algorithm");
            cbHashAlgorithm.DataBindings.Clear();
            cbHashAlgorithm.DataBindings.Add("SelectedItem", document, "HashAlgorithm");
            if (!document.Encrypted)
            {
                cbRecipient.Enabled = true;
                cbRecipient.DataBindings.Clear();
                cbRecipient.DataBindings.Add("SelectedItem", document, "Recipient");
                cbEncAlgorithm.Enabled = true;
            }
            cbHashAlgorithm.Enabled = !document.Signed;
            tabControlOperations.Enabled = true;
            SetButtonState();

        }

        private void SetButtonState()
        {
            if (document != null)
            {
                btnEncrypt.Enabled = document.CanBeEncrypted;
                btnDecrypt.Enabled = document.UserCanDecrypt(username);
                btnSign.Enabled = document.CanBeSigned;
                btnVerifySignature.Enabled = document.Signed;
                btnSaveDocument.Enabled = true;
                btnOpenFile.Enabled = btnOpenFile2.Enabled = !document.HasPayload;
                btnSavePayload.Enabled = btnSavePayload2.Enabled = document.HasPayload && !document.Encrypted;
            }
        }

        private void btnNewDocument_Click(object sender, EventArgs e)
        {
            document = new Document()
            {
                Author = username
            };
            BindDocumentInfo();
        }

        private void btnOpenDocument_Click(object sender, EventArgs e)
        {
            ofdDocument.ShowDialog();
        }

        private void ofdDocument_FileOk(object sender, CancelEventArgs e)
        {
            try
            {
                using (var stream = ofdDocument.OpenFile())
                {
                    document = Document.Deserialize(stream);                    
                }
                BindDocumentInfo();
            }
            catch (Exception ex)
            {
                MessageBox.Show(Resources.InvalidDocument);
            }
        }

        private void ofdPayload_FileOk(object sender, CancelEventArgs e)
        {
            try
            {
                using (System.IO.BinaryReader sr = new System.IO.BinaryReader (ofdPayload.OpenFile()))
                {
                    document.Payload = sr.ReadBytes((int)sr.BaseStream.Length);
                }
                document.Filename = ofdPayload.FileName;
                BindDocumentInfo();
            }
            catch (Exception ex)
            {
                MessageBox.Show(Resources.InvalidDocument);
            }
        }

        private void btnSavePayload_Click(object sender, EventArgs e)
        {
            string file = document.Filename;
            if (file.Contains('\\'))
            {
                file = file.Substring(document.Filename.LastIndexOf('\\') + 1);
            }
            sfdPayload.FileName = file;
            sfdPayload.ShowDialog();
        }

        private void sfdPayload_FileOk(object sender, CancelEventArgs e)
        {
            using (var stream = sfdPayload.OpenFile())
            {
                stream.Write(document.Payload, 0, document.Payload.Length);
            }
        }

        private void btnOpenFile_Click(object sender, EventArgs e)
        {
            ofdPayload.ShowDialog();
        }

        //private void button1_Click(object sender, EventArgs e)
        //{
        //    ofdPayload.ShowDialog();
        //}

        private void btnVerifySignature_Click(object sender, EventArgs e)
        {
            bool verified = Service.Verify(document);
            if (verified)
            {
                MessageBox.Show(Resources.SignatureValid);
            }
            else
            {
                MessageBox.Show(Resources.SignatureInvalid);
            }
        }

        private void btnDecrypt_Click(object sender, EventArgs e)
        {
            try
            {
                document = Service.Decrypt(document);
                SetButtonState();
            }
            catch (Exception ex)
            {
                MessageBox.Show(Resources.CannotDecrypt);
            }
        }

        private void btnSign_Click(object sender, EventArgs e)
        {
            try
            {
                document = Service.Sign(document);
                BindDocumentInfo();
            }
            catch (Exception ex)
            {
            }
        }

        private void btnEncrypt_Click(object sender, EventArgs e)
        {
            try
            {
                document = Service.Encrypt(document);
                BindDocumentInfo();
            }
            catch (Exception)
            {
                
                
            }
        }

        private void btnSaveDocument_Click(object sender, EventArgs e)
        {
            sfdDocument.ShowDialog();
        }

        private void sfdDocument_FileOk(object sender, CancelEventArgs e)
        {
            using (var stream = sfdDocument.OpenFile())
            {
                document.SerializeToStream(stream);
            }
        }

        private void cbEncAlgorithm_SelectedIndexChanged(object sender, EventArgs e)
        {
            SetButtonState();
        }

        private void cbHashAlgorithm_SelectedIndexChanged(object sender, EventArgs e)
        {
            SetButtonState();
        }


        private void cbRecipient_Enter(object sender, EventArgs e)
        {
            BindDocumentInfo();
        }
    }
}